# -*- encoding: utf-8 -*-
'''
file       :dynamics_demarcate_pix.py
Description:利用5*5像素中间像素为白色, 其余像素为黑色所拍摄所得的图像进行动态定位每个5*5色块的中心点位
Date       :2022/12/22 09:39:19
Author     :Josco
version    :python3.7.8
'''


from config import *
from public import *


class dynamics_demarcate_pix(object):
    def __init__(self) -> None:
        pass

    @staticmethod
    def local_start_pix(lp3, first_point_row_col):
        """根据rgb分量之和最大来找到初始点位"""
        start_point_matrix = lp3[:first_point_row_col[0],
                                 :first_point_row_col[1], :]
        start_point_matrix = start_point_matrix[:, :, 0] + \
            start_point_matrix[:, :, 1]+start_point_matrix[:, :, 2]
        start_point = np.where(start_point_matrix ==
                               np.max(start_point_matrix))
        # print(start_point)
        return [start_point[0][0], start_point[1][0]]

    def turn_pic(self, pic_path, ori_pic_path, camera):
        """
        desc: 把要验证的三个图片分片进行验证处理
        param:
            pic_path: 拍摄后的照片的路径
            local_list: 初始化原始图像时所用的宽高和放大倍数list
            ori_pic_path: 原始图像的路径
        """
        # 读取原始图像
        ori_img = cv.imread(ori_pic_path)

        top_bottom = top_bottom_black + top_bottom_white
        left_right = left_right_black + left_right_white
        ori_img = ori_img[top_bottom*n:-top_bottom*n,
                          left_right*n:-(left_right*n), :]
        # 将原始标准图像进行旋转后得
        ori_img = cv.rotate(ori_img, cv.ROTATE_90_COUNTERCLOCKWISE)
        # cv.imwrite("./DebugImg/standard/ori_img.bmp", ori_img)  # 存为图像

        print("现在开始进行动态矩阵的提取：")
        all_dynamics_point_matrix = []
        for pic_local in range(3):
            print("这是第%d个色块的动态提取信息, 其点位信息如下所示：" % (pic_local))
            dynamics_point_matrix = self.get_ori_pic_and_shotted_pic(
                pic_path, ori_img, pic_local, camera)
            # print(dynamics_point_matrix)
            all_dynamics_point_matrix.append(dynamics_point_matrix)
        return all_dynamics_point_matrix

    def get_ori_pic_and_shotted_pic(self, pic_path, ori_img, pic_local, camera):
        """
            desc: 根据输入的第几张图像选择好对应的原始图像和被拍摄后的图像
            param:
                pic_path: 被单个摄像头所拍摄的完整的图像相对路径
                ori_img: 旋转后的原始图像矩阵
                pic_local: 选择照片中的上中下三个位置的具体哪个位置
                camera: 对应哪个相机
            return:
                None
        """
        # 读取原始图像拍摄后的图像
        pic_img = cv.imread(pic_path)
        pic_width = int(height/3)  # 因为分为3块, 所以是height/3
        if pic_local == 0:
            # 获取
            start_x, stop_x, start_y, stop_y = camera[0]
            lp3 = pic_img[start_x:stop_x, start_y:stop_y]
            ori_img_matrix = ori_img[:, :pic_width*n, :]
            first_point_row_col = point_row_col[0]  # 选择照片对应的行列截至位置
            cv.imwrite("./DebugImg/standard/pic_img_" + str(pic_local) + ".bmp",
                       lp3)  # 存为图像
            cv.imwrite("./DebugImg/standard/ori_" + str(pic_local) + ".bmp",
                       ori_img_matrix)
        elif pic_local == 1:
            start_x, stop_x, start_y, stop_y = camera[1]
            lp3 = pic_img[start_x:stop_x, start_y:stop_y]
            first_point_row_col = point_row_col[1]  # 选择照片对应的行列截至位置
            ori_img_matrix = ori_img[:, (pic_width+2*(left_right_black+left_right_white))*n:
                                     (pic_width*2+2*(left_right_black+left_right_white))*n, :]
            cv.imwrite("./DebugImg/standard/pic_img_" + str(pic_local) + ".bmp",
                       lp3)  # 存为图像
            cv.imwrite("./DebugImg/standard/ori_" + str(pic_local) + ".bmp",
                       ori_img_matrix)
        else:
            start_x, stop_x, start_y, stop_y = camera[2]
            lp3 = pic_img[start_x:stop_x, start_y:stop_y]
            first_point_row_col = point_row_col[2]  # 选择照片对应的行列截至位置
            ori_img_matrix = ori_img[:, (pic_width+2 *
                                         (left_right_black+left_right_white))*n*2:, :]
            cv.imwrite("./DebugImg/standard/pic_img_" + str(pic_local) + ".bmp",
                       lp3)  # 存为图像
            cv.imwrite("./DebugImg/standard/ori_" + str(pic_local) + ".bmp",
                       ori_img_matrix)

        # 获取初始位置点的行和列
        start_point = self.local_start_pix(lp3, first_point_row_col)
        print("起始点在这里：", start_point[0], start_point[1])
        print("起始点的色值为：", lp3[start_point[0], start_point[1], :])
        dynamics_point_matrix = self.get_dynamics_point_matrix(
            lp3, start_point, int(height/3), width)  # 根据初始点像素位置通过动态锚定的方式获取其余像素点
        
        return dynamics_point_matrix

    @staticmethod
    def get_point_list(_row, _col):
        """根据row, col获取point_list"""
        point_list = []
        for _row_item in range(-2, 3):
            for _col_item in range(-2, 3):
                point_list.append([_row+_row_item, _col+_col_item])
        # print(point_list)
        return point_list

    def get_dynamics_point_matrix(self, lp3, start_point, width, height):
        """
        desc: 根据初始点像素位置通过动态锚定的方式获取其余像素点
        param:
            lp3:         截取拍摄所得的图像, 截取到的图像周围都有一圈白色的部分包裹着里面的伪二维码
            ori_img_1:   原始的图像色值部分, 是一个1*1代表一个色块的伪二维码
            start_point: 起始点
            width:       伪二维码原始宽度
            height:      伪二维码的原始宽度/3, 因为一张伪二维码被切割成三分
        return:
            dynamics_point_matrix: 动态点位矩阵
        """
        # 确定起始像素的位置
        first_row = start_point[0]
        first_col = start_point[1]
        print(width, height)

        dynamics_point_matrix = []  # 所有动态点位存储的list
        for _row in range(height):
            # 每行第一个点位的位置周边两层的point坐标
            first_point_list = self.get_point_list(first_row, first_col)
            # 验证每行位第一列的位置最大的点所在行和列
            first_row, first_col, is_find_center = self.demarcate_point(
                lp3, first_row, first_col, first_point_list)
            # print("first_row, first_col", first_row, first_col)
            if is_find_center == False:
                print("first_row:%d, first_col:%d:********************************row: %d" %
                      (first_row, first_col, _row))
                print(
                    "找第%d行的头个数据出错+++++++++" % (first_row))
                return None
            start_point_col = first_col  # 获取起始点的行
            start_point_row = first_row  # 获取每一行的起始点的列
            for _col in range(width):
                point_list = self.get_point_list(
                    start_point_row, start_point_col)
                start_point_row, start_point_col, is_find_center = self.demarcate_point(
                    lp3, start_point_row, start_point_col, point_list)
                if is_find_center == False:
                    print("找第%d行%d列的数据出错------------" %
                          (start_point_row, start_point_col))
                    return None
                dynamics_point_matrix.append(
                    [start_point_row, start_point_col])
                start_point_col += row_col_dis
            first_row += row_col_dis

        return np.array(dynamics_point_matrix)

    def demarcate_point(self, lp3, start_point_row, start_point_col, point_list):
        """
            desc: 根据最大值查找拍摄后照片中的5*5色块的中心点
            param:
                lp3:         截取拍摄所得的图像, 截取到的图像周围都有一圈白色的部分包裹着里面的伪二维码
                start_point_row, start_point_col: 拍摄后每个色块的初始位置
                point_list:  根据start_point_row, start_point_col计算所得25个点位的list
            return:
                first_point_loc[0], first_point_loc[1]: 动态点位的行和列
                is_find_center: 是否查找成功, 判断条件是r,g,b分量三色的值之和是否大于60
        """
        color_list = []
        for _point in point_list:
            color_list.append(np.sum(lp3[_point[0], _point[1]]))
        color_list = np.array(color_list)
        max_color_point_loc = np.where(color_list == np.max(color_list))
        if np.max(color_list) < 20:
            print("最大值都小于20, 返回错误!")
            print(color_list)
            return start_point_row, start_point_col, False
        first_point_loc = point_list[max_color_point_loc[0][0]]
        # print("first_point_loc", first_point_loc)
        return first_point_loc[0], first_point_loc[1], True
